diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-03-08 01:07:33 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-03-08 01:07:33 +0000 |
commit | 5d3310208ae811396ca0cf256f96d4234ce5ae75 (patch) | |
tree | e7978b11cce7633f20a865762d372bc5de374c8a /clang/lib/Sema/SemaTemplate.cpp | |
parent | c13d858b6dffc2b31e2348dac2fa7958f4009298 (diff) | |
download | bcm5719-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.cpp | 26 |
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. |