Skip to content

Commit 37acb79

Browse files
committed
Refactor conversion of deduced template arguments to reduce repetition.
llvm-svn: 259687
1 parent f5935a0 commit 37acb79

File tree

1 file changed

+49
-103
lines changed

1 file changed

+49
-103
lines changed

clang/lib/Sema/SemaTemplateDeduction.cpp

Lines changed: 49 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -2060,11 +2060,46 @@ static bool
20602060
ConvertDeducedTemplateArgument(Sema &S, NamedDecl *Param,
20612061
DeducedTemplateArgument Arg,
20622062
NamedDecl *Template,
2063-
QualType NTTPType,
2064-
unsigned ArgumentPackIndex,
20652063
TemplateDeductionInfo &Info,
20662064
bool InFunctionTemplate,
20672065
SmallVectorImpl<TemplateArgument> &Output) {
2066+
// First, for a non-type template parameter type that is
2067+
// initialized by a declaration, we need the type of the
2068+
// corresponding non-type template parameter.
2069+
QualType NTTPType;
2070+
if (NonTypeTemplateParmDecl *NTTP =
2071+
dyn_cast<NonTypeTemplateParmDecl>(Param)) {
2072+
NTTPType = NTTP->getType();
2073+
if (NTTPType->isDependentType()) {
2074+
TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
2075+
Output.data(), Output.size());
2076+
NTTPType = S.SubstType(NTTPType,
2077+
MultiLevelTemplateArgumentList(TemplateArgs),
2078+
NTTP->getLocation(),
2079+
NTTP->getDeclName());
2080+
if (NTTPType.isNull())
2081+
return true;
2082+
}
2083+
}
2084+
2085+
auto ConvertArg = [&](DeducedTemplateArgument Arg,
2086+
unsigned ArgumentPackIndex) {
2087+
// Convert the deduced template argument into a template
2088+
// argument that we can check, almost as if the user had written
2089+
// the template argument explicitly.
2090+
TemplateArgumentLoc ArgLoc =
2091+
getTrivialTemplateArgumentLoc(S, Arg, NTTPType, Info.getLocation());
2092+
2093+
// Check the template argument, converting it as necessary.
2094+
return S.CheckTemplateArgument(
2095+
Param, ArgLoc, Template, Template->getLocation(),
2096+
Template->getSourceRange().getEnd(), ArgumentPackIndex, Output,
2097+
InFunctionTemplate
2098+
? (Arg.wasDeducedFromArrayBound() ? Sema::CTAK_DeducedFromArrayBound
2099+
: Sema::CTAK_Deduced)
2100+
: Sema::CTAK_Specified);
2101+
};
2102+
20682103
if (Arg.getKind() == TemplateArgument::Pack) {
20692104
// This is a template argument pack, so check each of its arguments against
20702105
// the template parameter.
@@ -2075,39 +2110,25 @@ ConvertDeducedTemplateArgument(Sema &S, NamedDecl *Param,
20752110
// checking logic has all of the prior template arguments available.
20762111
DeducedTemplateArgument InnerArg(P);
20772112
InnerArg.setDeducedFromArrayBound(Arg.wasDeducedFromArrayBound());
2078-
if (ConvertDeducedTemplateArgument(S, Param, InnerArg, Template,
2079-
NTTPType, PackedArgsBuilder.size(),
2080-
Info, InFunctionTemplate, Output))
2113+
assert(InnerArg.getKind() != TemplateArgument::Pack &&
2114+
"deduced nested pack");
2115+
if (ConvertArg(InnerArg, PackedArgsBuilder.size()))
20812116
return true;
20822117

20832118
// Move the converted template argument into our argument pack.
20842119
PackedArgsBuilder.push_back(Output.pop_back_val());
20852120
}
20862121

2122+
// FIXME: If the pack is empty and this is a template template parameter,
2123+
// we still need to substitute into the parameter itself.
2124+
20872125
// Create the resulting argument pack.
20882126
Output.push_back(
20892127
TemplateArgument::CreatePackCopy(S.Context, PackedArgsBuilder));
20902128
return false;
20912129
}
20922130

2093-
// Convert the deduced template argument into a template
2094-
// argument that we can check, almost as if the user had written
2095-
// the template argument explicitly.
2096-
TemplateArgumentLoc ArgLoc = getTrivialTemplateArgumentLoc(S, Arg, NTTPType,
2097-
Info.getLocation());
2098-
2099-
// Check the template argument, converting it as necessary.
2100-
return S.CheckTemplateArgument(Param, ArgLoc,
2101-
Template,
2102-
Template->getLocation(),
2103-
Template->getSourceRange().getEnd(),
2104-
ArgumentPackIndex,
2105-
Output,
2106-
InFunctionTemplate
2107-
? (Arg.wasDeducedFromArrayBound()
2108-
? Sema::CTAK_DeducedFromArrayBound
2109-
: Sema::CTAK_Deduced)
2110-
: Sema::CTAK_Specified);
2131+
return ConvertArg(Arg, 0);
21112132
}
21122133

21132134
/// Complete template argument deduction for a class template partial
@@ -2138,34 +2159,8 @@ FinishTemplateArgumentDeduction(Sema &S,
21382159

21392160
// We have deduced this argument, so it still needs to be
21402161
// checked and converted.
2141-
2142-
// First, for a non-type template parameter type that is
2143-
// initialized by a declaration, we need the type of the
2144-
// corresponding non-type template parameter.
2145-
QualType NTTPType;
2146-
if (NonTypeTemplateParmDecl *NTTP
2147-
= dyn_cast<NonTypeTemplateParmDecl>(Param)) {
2148-
NTTPType = NTTP->getType();
2149-
if (NTTPType->isDependentType()) {
2150-
TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
2151-
Builder.data(), Builder.size());
2152-
NTTPType = S.SubstType(NTTPType,
2153-
MultiLevelTemplateArgumentList(TemplateArgs),
2154-
NTTP->getLocation(),
2155-
NTTP->getDeclName());
2156-
if (NTTPType.isNull()) {
2157-
Info.Param = makeTemplateParameter(Param);
2158-
// FIXME: These template arguments are temporary. Free them!
2159-
Info.reset(TemplateArgumentList::CreateCopy(S.Context,
2160-
Builder.data(),
2161-
Builder.size()));
2162-
return Sema::TDK_SubstitutionFailure;
2163-
}
2164-
}
2165-
}
2166-
21672162
if (ConvertDeducedTemplateArgument(S, Param, Deduced[I],
2168-
Partial, NTTPType, 0, Info, false,
2163+
Partial, Info, false,
21692164
Builder)) {
21702165
Info.Param = makeTemplateParameter(Param);
21712166
// FIXME: These template arguments are temporary. Free them!
@@ -2306,32 +2301,8 @@ static Sema::TemplateDeductionResult FinishTemplateArgumentDeduction(
23062301

23072302
// We have deduced this argument, so it still needs to be
23082303
// checked and converted.
2309-
2310-
// First, for a non-type template parameter type that is
2311-
// initialized by a declaration, we need the type of the
2312-
// corresponding non-type template parameter.
2313-
QualType NTTPType;
2314-
if (NonTypeTemplateParmDecl *NTTP =
2315-
dyn_cast<NonTypeTemplateParmDecl>(Param)) {
2316-
NTTPType = NTTP->getType();
2317-
if (NTTPType->isDependentType()) {
2318-
TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
2319-
Builder.data(), Builder.size());
2320-
NTTPType =
2321-
S.SubstType(NTTPType, MultiLevelTemplateArgumentList(TemplateArgs),
2322-
NTTP->getLocation(), NTTP->getDeclName());
2323-
if (NTTPType.isNull()) {
2324-
Info.Param = makeTemplateParameter(Param);
2325-
// FIXME: These template arguments are temporary. Free them!
2326-
Info.reset(TemplateArgumentList::CreateCopy(S.Context, Builder.data(),
2327-
Builder.size()));
2328-
return Sema::TDK_SubstitutionFailure;
2329-
}
2330-
}
2331-
}
2332-
2333-
if (ConvertDeducedTemplateArgument(S, Param, Deduced[I], Partial, NTTPType,
2334-
0, Info, false, Builder)) {
2304+
if (ConvertDeducedTemplateArgument(S, Param, Deduced[I], Partial,
2305+
Info, false, Builder)) {
23352306
Info.Param = makeTemplateParameter(Param);
23362307
// FIXME: These template arguments are temporary. Free them!
23372308
Info.reset(TemplateArgumentList::CreateCopy(S.Context, Builder.data(),
@@ -2804,36 +2775,11 @@ Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate,
28042775
}
28052776
continue;
28062777
}
2778+
28072779
// We have deduced this argument, so it still needs to be
28082780
// checked and converted.
2809-
2810-
// First, for a non-type template parameter type that is
2811-
// initialized by a declaration, we need the type of the
2812-
// corresponding non-type template parameter.
2813-
QualType NTTPType;
2814-
if (NonTypeTemplateParmDecl *NTTP
2815-
= dyn_cast<NonTypeTemplateParmDecl>(Param)) {
2816-
NTTPType = NTTP->getType();
2817-
if (NTTPType->isDependentType()) {
2818-
TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
2819-
Builder.data(), Builder.size());
2820-
NTTPType = SubstType(NTTPType,
2821-
MultiLevelTemplateArgumentList(TemplateArgs),
2822-
NTTP->getLocation(),
2823-
NTTP->getDeclName());
2824-
if (NTTPType.isNull()) {
2825-
Info.Param = makeTemplateParameter(Param);
2826-
// FIXME: These template arguments are temporary. Free them!
2827-
Info.reset(TemplateArgumentList::CreateCopy(Context,
2828-
Builder.data(),
2829-
Builder.size()));
2830-
return TDK_SubstitutionFailure;
2831-
}
2832-
}
2833-
}
2834-
28352781
if (ConvertDeducedTemplateArgument(*this, Param, Deduced[I],
2836-
FunctionTemplate, NTTPType, 0, Info,
2782+
FunctionTemplate, Info,
28372783
true, Builder)) {
28382784
Info.Param = makeTemplateParameter(Param);
28392785
// FIXME: These template arguments are temporary. Free them!

0 commit comments

Comments
 (0)