forked from OSchip/llvm-project
Refactor conversion of deduced template arguments to reduce repetition.
llvm-svn: 259687
This commit is contained in:
parent
f5935a0abc
commit
37acb79084
|
@ -2060,11 +2060,46 @@ static bool
|
|||
ConvertDeducedTemplateArgument(Sema &S, NamedDecl *Param,
|
||||
DeducedTemplateArgument Arg,
|
||||
NamedDecl *Template,
|
||||
QualType NTTPType,
|
||||
unsigned ArgumentPackIndex,
|
||||
TemplateDeductionInfo &Info,
|
||||
bool InFunctionTemplate,
|
||||
SmallVectorImpl<TemplateArgument> &Output) {
|
||||
// First, for a non-type template parameter type that is
|
||||
// initialized by a declaration, we need the type of the
|
||||
// corresponding non-type template parameter.
|
||||
QualType NTTPType;
|
||||
if (NonTypeTemplateParmDecl *NTTP =
|
||||
dyn_cast<NonTypeTemplateParmDecl>(Param)) {
|
||||
NTTPType = NTTP->getType();
|
||||
if (NTTPType->isDependentType()) {
|
||||
TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
|
||||
Output.data(), Output.size());
|
||||
NTTPType = S.SubstType(NTTPType,
|
||||
MultiLevelTemplateArgumentList(TemplateArgs),
|
||||
NTTP->getLocation(),
|
||||
NTTP->getDeclName());
|
||||
if (NTTPType.isNull())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
auto ConvertArg = [&](DeducedTemplateArgument Arg,
|
||||
unsigned ArgumentPackIndex) {
|
||||
// Convert the deduced template argument into a template
|
||||
// argument that we can check, almost as if the user had written
|
||||
// the template argument explicitly.
|
||||
TemplateArgumentLoc ArgLoc =
|
||||
getTrivialTemplateArgumentLoc(S, Arg, NTTPType, Info.getLocation());
|
||||
|
||||
// Check the template argument, converting it as necessary.
|
||||
return S.CheckTemplateArgument(
|
||||
Param, ArgLoc, Template, Template->getLocation(),
|
||||
Template->getSourceRange().getEnd(), ArgumentPackIndex, Output,
|
||||
InFunctionTemplate
|
||||
? (Arg.wasDeducedFromArrayBound() ? Sema::CTAK_DeducedFromArrayBound
|
||||
: Sema::CTAK_Deduced)
|
||||
: Sema::CTAK_Specified);
|
||||
};
|
||||
|
||||
if (Arg.getKind() == TemplateArgument::Pack) {
|
||||
// This is a template argument pack, so check each of its arguments against
|
||||
// the template parameter.
|
||||
|
@ -2075,39 +2110,25 @@ ConvertDeducedTemplateArgument(Sema &S, NamedDecl *Param,
|
|||
// checking logic has all of the prior template arguments available.
|
||||
DeducedTemplateArgument InnerArg(P);
|
||||
InnerArg.setDeducedFromArrayBound(Arg.wasDeducedFromArrayBound());
|
||||
if (ConvertDeducedTemplateArgument(S, Param, InnerArg, Template,
|
||||
NTTPType, PackedArgsBuilder.size(),
|
||||
Info, InFunctionTemplate, Output))
|
||||
assert(InnerArg.getKind() != TemplateArgument::Pack &&
|
||||
"deduced nested pack");
|
||||
if (ConvertArg(InnerArg, PackedArgsBuilder.size()))
|
||||
return true;
|
||||
|
||||
// Move the converted template argument into our argument pack.
|
||||
PackedArgsBuilder.push_back(Output.pop_back_val());
|
||||
}
|
||||
|
||||
// FIXME: If the pack is empty and this is a template template parameter,
|
||||
// we still need to substitute into the parameter itself.
|
||||
|
||||
// Create the resulting argument pack.
|
||||
Output.push_back(
|
||||
TemplateArgument::CreatePackCopy(S.Context, PackedArgsBuilder));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Convert the deduced template argument into a template
|
||||
// argument that we can check, almost as if the user had written
|
||||
// the template argument explicitly.
|
||||
TemplateArgumentLoc ArgLoc = getTrivialTemplateArgumentLoc(S, Arg, NTTPType,
|
||||
Info.getLocation());
|
||||
|
||||
// Check the template argument, converting it as necessary.
|
||||
return S.CheckTemplateArgument(Param, ArgLoc,
|
||||
Template,
|
||||
Template->getLocation(),
|
||||
Template->getSourceRange().getEnd(),
|
||||
ArgumentPackIndex,
|
||||
Output,
|
||||
InFunctionTemplate
|
||||
? (Arg.wasDeducedFromArrayBound()
|
||||
? Sema::CTAK_DeducedFromArrayBound
|
||||
: Sema::CTAK_Deduced)
|
||||
: Sema::CTAK_Specified);
|
||||
return ConvertArg(Arg, 0);
|
||||
}
|
||||
|
||||
/// Complete template argument deduction for a class template partial
|
||||
|
@ -2138,34 +2159,8 @@ FinishTemplateArgumentDeduction(Sema &S,
|
|||
|
||||
// We have deduced this argument, so it still needs to be
|
||||
// checked and converted.
|
||||
|
||||
// First, for a non-type template parameter type that is
|
||||
// initialized by a declaration, we need the type of the
|
||||
// corresponding non-type template parameter.
|
||||
QualType NTTPType;
|
||||
if (NonTypeTemplateParmDecl *NTTP
|
||||
= dyn_cast<NonTypeTemplateParmDecl>(Param)) {
|
||||
NTTPType = NTTP->getType();
|
||||
if (NTTPType->isDependentType()) {
|
||||
TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
|
||||
Builder.data(), Builder.size());
|
||||
NTTPType = S.SubstType(NTTPType,
|
||||
MultiLevelTemplateArgumentList(TemplateArgs),
|
||||
NTTP->getLocation(),
|
||||
NTTP->getDeclName());
|
||||
if (NTTPType.isNull()) {
|
||||
Info.Param = makeTemplateParameter(Param);
|
||||
// FIXME: These template arguments are temporary. Free them!
|
||||
Info.reset(TemplateArgumentList::CreateCopy(S.Context,
|
||||
Builder.data(),
|
||||
Builder.size()));
|
||||
return Sema::TDK_SubstitutionFailure;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ConvertDeducedTemplateArgument(S, Param, Deduced[I],
|
||||
Partial, NTTPType, 0, Info, false,
|
||||
Partial, Info, false,
|
||||
Builder)) {
|
||||
Info.Param = makeTemplateParameter(Param);
|
||||
// FIXME: These template arguments are temporary. Free them!
|
||||
|
@ -2306,32 +2301,8 @@ static Sema::TemplateDeductionResult FinishTemplateArgumentDeduction(
|
|||
|
||||
// We have deduced this argument, so it still needs to be
|
||||
// checked and converted.
|
||||
|
||||
// First, for a non-type template parameter type that is
|
||||
// initialized by a declaration, we need the type of the
|
||||
// corresponding non-type template parameter.
|
||||
QualType NTTPType;
|
||||
if (NonTypeTemplateParmDecl *NTTP =
|
||||
dyn_cast<NonTypeTemplateParmDecl>(Param)) {
|
||||
NTTPType = NTTP->getType();
|
||||
if (NTTPType->isDependentType()) {
|
||||
TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
|
||||
Builder.data(), Builder.size());
|
||||
NTTPType =
|
||||
S.SubstType(NTTPType, MultiLevelTemplateArgumentList(TemplateArgs),
|
||||
NTTP->getLocation(), NTTP->getDeclName());
|
||||
if (NTTPType.isNull()) {
|
||||
Info.Param = makeTemplateParameter(Param);
|
||||
// FIXME: These template arguments are temporary. Free them!
|
||||
Info.reset(TemplateArgumentList::CreateCopy(S.Context, Builder.data(),
|
||||
Builder.size()));
|
||||
return Sema::TDK_SubstitutionFailure;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ConvertDeducedTemplateArgument(S, Param, Deduced[I], Partial, NTTPType,
|
||||
0, Info, false, Builder)) {
|
||||
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.data(),
|
||||
|
@ -2804,36 +2775,11 @@ Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate,
|
|||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// We have deduced this argument, so it still needs to be
|
||||
// checked and converted.
|
||||
|
||||
// First, for a non-type template parameter type that is
|
||||
// initialized by a declaration, we need the type of the
|
||||
// corresponding non-type template parameter.
|
||||
QualType NTTPType;
|
||||
if (NonTypeTemplateParmDecl *NTTP
|
||||
= dyn_cast<NonTypeTemplateParmDecl>(Param)) {
|
||||
NTTPType = NTTP->getType();
|
||||
if (NTTPType->isDependentType()) {
|
||||
TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
|
||||
Builder.data(), Builder.size());
|
||||
NTTPType = SubstType(NTTPType,
|
||||
MultiLevelTemplateArgumentList(TemplateArgs),
|
||||
NTTP->getLocation(),
|
||||
NTTP->getDeclName());
|
||||
if (NTTPType.isNull()) {
|
||||
Info.Param = makeTemplateParameter(Param);
|
||||
// FIXME: These template arguments are temporary. Free them!
|
||||
Info.reset(TemplateArgumentList::CreateCopy(Context,
|
||||
Builder.data(),
|
||||
Builder.size()));
|
||||
return TDK_SubstitutionFailure;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ConvertDeducedTemplateArgument(*this, Param, Deduced[I],
|
||||
FunctionTemplate, NTTPType, 0, Info,
|
||||
FunctionTemplate, Info,
|
||||
true, Builder)) {
|
||||
Info.Param = makeTemplateParameter(Param);
|
||||
// FIXME: These template arguments are temporary. Free them!
|
||||
|
|
Loading…
Reference in New Issue