[cfe-commits] r86844 - in /cfe/trunk: lib/Sema/SemaTemplateInstantiateDecl.cpp test/SemaTemplate/nested-template.cpp
Douglas Gregor
dgregor at apple.com
Wed Nov 11 08:58:32 PST 2009
Author: dgregor
Date: Wed Nov 11 10:58:32 2009
New Revision: 86844
URL: http://llvm.org/viewvc/llvm-project?rev=86844&view=rev
Log:
Instantiation of template template parameters for nested templates, e.g.,
template<typename T>
struct X {
template<template<T Value> class Y> struct Inner;
};
Modified:
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/test/SemaTemplate/nested-template.cpp
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=86844&r1=86843&r2=86844&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed Nov 11 10:58:32 2009
@@ -64,6 +64,7 @@
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.
@@ -974,6 +975,35 @@
}
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 =
SemaRef.SubstNestedNameSpecifier(D->getTargetNestedNameSpecifier(),
Modified: cfe/trunk/test/SemaTemplate/nested-template.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/nested-template.cpp?rev=86844&r1=86843&r2=86844&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/nested-template.cpp (original)
+++ cfe/trunk/test/SemaTemplate/nested-template.cpp Wed Nov 11 10:58:32 2009
@@ -108,3 +108,21 @@
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}}
+
+
More information about the cfe-commits
mailing list