зеркало из https://github.com/microsoft/clang-1.git
Instantiation of template template parameters for nested templates, e.g.,
template<typename T> struct X { template<template<T Value> class Y> struct Inner; }; git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@86844 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
7bb87fca7d
Коммит
9106ef78f8
|
@ -64,6 +64,7 @@ namespace {
|
|||
Decl *VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
|
||||
Decl *VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
|
||||
Decl *VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
|
||||
Decl *VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
|
||||
Decl *VisitUnresolvedUsingDecl(UnresolvedUsingDecl *D);
|
||||
|
||||
// Base case. FIXME: Remove once we can instantiate everything.
|
||||
|
@ -973,6 +974,35 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl(
|
|||
return Param;
|
||||
}
|
||||
|
||||
Decl *
|
||||
TemplateDeclInstantiator::VisitTemplateTemplateParmDecl(
|
||||
TemplateTemplateParmDecl *D) {
|
||||
// Instantiate the template parameter list of the template template parameter.
|
||||
TemplateParameterList *TempParams = D->getTemplateParameters();
|
||||
TemplateParameterList *InstParams;
|
||||
{
|
||||
// Perform the actual substitution of template parameters within a new,
|
||||
// local instantiation scope.
|
||||
Sema::LocalInstantiationScope Scope(SemaRef);
|
||||
InstParams = SubstTemplateParams(TempParams);
|
||||
if (!InstParams)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Build the template template parameter.
|
||||
TemplateTemplateParmDecl *Param
|
||||
= TemplateTemplateParmDecl::Create(SemaRef.Context, Owner, D->getLocation(),
|
||||
D->getDepth() - 1, D->getPosition(),
|
||||
D->getIdentifier(), InstParams);
|
||||
Param->setDefaultArgument(D->getDefaultArgument());
|
||||
|
||||
// Introduce this template parameter's instantiation into the instantiation
|
||||
// scope.
|
||||
SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Param);
|
||||
|
||||
return Param;
|
||||
}
|
||||
|
||||
Decl *
|
||||
TemplateDeclInstantiator::VisitUnresolvedUsingDecl(UnresolvedUsingDecl *D) {
|
||||
NestedNameSpecifier *NNS =
|
||||
|
|
|
@ -108,3 +108,21 @@ struct X1 {
|
|||
template<typename, bool = false> struct B { };
|
||||
};
|
||||
template struct X1<int>::B<bool>;
|
||||
|
||||
// Template template parameters
|
||||
template<typename T>
|
||||
struct X2 {
|
||||
template<template<class U, T Value> class> // expected-error{{cannot have type 'float'}} \
|
||||
// expected-note{{previous non-type template}}
|
||||
struct Inner { };
|
||||
};
|
||||
|
||||
template<typename T,
|
||||
int Value> // expected-note{{template non-type parameter}}
|
||||
struct X2_arg;
|
||||
|
||||
X2<int>::Inner<X2_arg> x2i1;
|
||||
X2<float>::Inner<X2_arg> x2i2; // expected-note{{instantiation}}
|
||||
X2<long>::Inner<X2_arg> x2i3; // expected-error{{template template argument has different}}
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче