]> granicus.if.org Git - clang/commitdiff
Implement template instantiation for non-type template
authorDouglas Gregor <dgregor@apple.com>
Fri, 23 Oct 2009 23:25:44 +0000 (23:25 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 23 Oct 2009 23:25:44 +0000 (23:25 +0000)
parameters. Fixes PR5103.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84979 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaTemplateInstantiateDecl.cpp
test/SemaTemplate/nested-template.cpp

index 00f148df6e6b2e0ff384de0ddff7c7182a1acc0c..c30f48e803a7434dd175a425b656c169a0abd0b6 100644 (file)
@@ -61,6 +61,7 @@ namespace {
                                     ClassTemplatePartialSpecializationDecl *D);
     Decl *VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
     Decl *VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
+    Decl *VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
     Decl *VisitUnresolvedUsingDecl(UnresolvedUsingDecl *D);
 
     // Base case. FIXME: Remove once we can instantiate everything.
@@ -824,6 +825,8 @@ Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl(
                                  D->wasDeclaredWithTypename(),
                                  D->isParameterPack());
 
+  // FIXME: Do we actually want to perform substitution here? I don't think
+  // we do.
   if (D->hasDefaultArgument()) {
     QualType DefaultPattern = D->getDefaultArgument();
     QualType DefaultInst
@@ -839,6 +842,42 @@ Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl(
   return Inst;
 }
 
+Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl(
+                                                 NonTypeTemplateParmDecl *D) {
+  // Substitute into the type of the non-type template parameter.
+  QualType T;
+  DeclaratorInfo *DI = D->getDeclaratorInfo();
+  if (DI) {
+    DI = SemaRef.SubstType(DI, TemplateArgs, D->getLocation(),
+                           D->getDeclName());
+    if (DI) T = DI->getType();
+  } else {
+    T = SemaRef.SubstType(D->getType(), TemplateArgs, D->getLocation(),
+                          D->getDeclName());
+    DI = 0;
+  }
+  if (T.isNull())
+    return 0;
+  
+  // Check that this type is acceptable for a non-type template parameter.
+  bool Invalid = false;
+  T = SemaRef.CheckNonTypeTemplateParameterType(T, D->getLocation());
+  if (T.isNull()) {
+    T = SemaRef.Context.IntTy;
+    Invalid = true;
+  }
+  
+  NonTypeTemplateParmDecl *Param
+    = NonTypeTemplateParmDecl::Create(SemaRef.Context, Owner, D->getLocation(),
+                                      D->getDepth() - 1, D->getPosition(),
+                                      D->getIdentifier(), T, DI);
+  if (Invalid)
+    Param->setInvalidDecl();
+  
+  Param->setDefaultArgument(D->getDefaultArgument());
+  return Param;
+}
+
 Decl *
 TemplateDeclInstantiator::VisitUnresolvedUsingDecl(UnresolvedUsingDecl *D) {
   NestedNameSpecifier *NNS =
index 5ee2c9954005e3856268879817359fa78caf243e..4d948184cee9da2ed332a41624aa580243bc26fc 100644 (file)
@@ -101,3 +101,10 @@ struct X0<T*> {
   template<typename U>
   void f(U u = T()) { }
 };
+
+// PR5103
+template<typename>
+struct X1 {
+  template<typename, bool = false> struct B { };
+};
+template struct X1<int>::B<bool>;