summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaTemplate.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2018-03-08 01:07:33 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2018-03-08 01:07:33 +0000
commit5d3310208ae811396ca0cf256f96d4234ce5ae75 (patch)
treee7978b11cce7633f20a865762d372bc5de374c8a /clang/lib/Sema/SemaTemplate.cpp
parentc13d858b6dffc2b31e2348dac2fa7958f4009298 (diff)
downloadbcm5719-llvm-5d3310208ae811396ca0cf256f96d4234ce5ae75.tar.gz
bcm5719-llvm-5d3310208ae811396ca0cf256f96d4234ce5ae75.zip
When substituting previously-checked template arguments into a template
template parameter that is an expanded parameter pack, only substitute into the current slice, not the entire pack. This reduces the checking of N template template arguments for an expanded parameter pack containing N parameters from quadratic time to linear time in the length of the pack. This is important because one (and possibly the only?) general technique for splitting a template parameter pack in linear time depends on doing this. llvm-svn: 326973
Diffstat (limited to 'clang/lib/Sema/SemaTemplate.cpp')
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp26
1 files changed, 14 insertions, 12 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 2e8a7061d71..12a74c1b64b 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -4617,6 +4617,8 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param,
if (NTTP->isParameterPack() && NTTP->isExpandedParameterPack())
NTTPType = NTTP->getExpansionType(ArgumentPackIndex);
+ // FIXME: Do we need to substitute into parameters here if they're
+ // instantiation-dependent but not dependent?
if (NTTPType->isDependentType() &&
!isa<TemplateTemplateParmDecl>(Template) &&
!Template->getDeclContext()->isDependentContext()) {
@@ -4756,9 +4758,15 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param,
// Check template template parameters.
TemplateTemplateParmDecl *TempParm = cast<TemplateTemplateParmDecl>(Param);
+ TemplateParameterList *Params = TempParm->getTemplateParameters();
+ if (TempParm->isExpandedParameterPack())
+ Params = TempParm->getExpansionTemplateParameters(ArgumentPackIndex);
+
// Substitute into the template parameter list of the template
// template parameter, since previously-supplied template arguments
// may appear within the template template parameter.
+ //
+ // FIXME: Skip this if the parameters aren't instantiation-dependent.
{
// Set up a template instantiation context.
LocalInstantiationScope Scope(*this);
@@ -4769,10 +4777,9 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param,
return true;
TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, Converted);
- TempParm = cast_or_null<TemplateTemplateParmDecl>(
- SubstDecl(TempParm, CurContext,
- MultiLevelTemplateArgumentList(TemplateArgs)));
- if (!TempParm)
+ Params = SubstTemplateParams(Params, CurContext,
+ MultiLevelTemplateArgumentList(TemplateArgs));
+ if (!Params)
return true;
}
@@ -4793,7 +4800,7 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param,
case TemplateArgument::Template:
case TemplateArgument::TemplateExpansion:
- if (CheckTemplateArgument(TempParm, Arg, ArgumentPackIndex))
+ if (CheckTemplateTemplateArgument(Params, Arg))
return true;
Converted.push_back(Arg.getArgument());
@@ -6536,9 +6543,8 @@ static void DiagnoseTemplateParameterListArityMismatch(
///
/// This routine implements the semantics of C++ [temp.arg.template].
/// It returns true if an error occurred, and false otherwise.
-bool Sema::CheckTemplateArgument(TemplateTemplateParmDecl *Param,
- TemplateArgumentLoc &Arg,
- unsigned ArgumentPackIndex) {
+bool Sema::CheckTemplateTemplateArgument(TemplateParameterList *Params,
+ TemplateArgumentLoc &Arg) {
TemplateName Name = Arg.getArgument().getAsTemplateOrTemplatePattern();
TemplateDecl *Template = Name.getAsTemplateDecl();
if (!Template) {
@@ -6573,10 +6579,6 @@ bool Sema::CheckTemplateArgument(TemplateTemplateParmDecl *Param,
<< Template;
}
- TemplateParameterList *Params = Param->getTemplateParameters();
- if (Param->isExpandedParameterPack())
- Params = Param->getExpansionTemplateParameters(ArgumentPackIndex);
-
// C++1z [temp.arg.template]p3: (DR 150)
// A template-argument matches a template template-parameter P when P
// is at least as specialized as the template-argument A.
OpenPOWER on IntegriCloud