]> granicus.if.org Git - clang/commitdiff
Fix a thinko in a helper routine for template argument deduction that
authorDouglas Gregor <dgregor@apple.com>
Fri, 24 Dec 2010 00:35:52 +0000 (00:35 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 24 Dec 2010 00:35:52 +0000 (00:35 +0000)
caused an assertion when dealing with non-type template parameter
packs. Add some tests for deduction and instantiation of non-type
template parameter packs.

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

lib/Sema/SemaTemplateDeduction.cpp
test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp

index 90894f22a36dc43278ea709018a852fa0690dec5..4a667cdf57ce34dabb0029c5239677f5d7cad24e 100644 (file)
@@ -1037,14 +1037,14 @@ getDepthAndIndex(UnexpandedParameterPack UPP) {
                           = UPP.first.dyn_cast<const TemplateTypeParmType *>())
     return std::make_pair(TTP->getDepth(), TTP->getIndex());
   
-  if (TemplateTypeParmDecl *TTP = UPP.first.dyn_cast<TemplateTypeParmDecl *>())
+  NamedDecl *ND = UPP.first.get<NamedDecl *>();
+  if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ND))
     return std::make_pair(TTP->getDepth(), TTP->getIndex());
   
-  if (NonTypeTemplateParmDecl *NTTP 
-                              = UPP.first.dyn_cast<NonTypeTemplateParmDecl *>())
+  if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(ND))
     return std::make_pair(NTTP->getDepth(), NTTP->getIndex());
   
-  TemplateTemplateParmDecl *TTP = UPP.first.get<TemplateTemplateParmDecl *>();
+  TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(ND);
   return std::make_pair(TTP->getDepth(), TTP->getIndex());
 }
 
index ebfcd3808e6d19affd6151875e55cd8b18d7c107..508722437c39e785d7460c84287f1582f56235c3 100644 (file)
@@ -1,6 +1,17 @@
 // RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
 
 template<typename ...Types> struct tuple;
+template<unsigned> struct unsigned_c;
+
+template<typename T, typename U> 
+struct is_same {
+  static const bool value = false;
+};
+
+template<typename T>
+struct is_same<T, T> {
+  static const bool value = true;
+};
 
 namespace PackExpansionNotAtEnd {
   template<typename T, typename U>
@@ -19,7 +30,26 @@ namespace PackExpansionNotAtEnd {
 
   template<typename ... Types> struct UselessPartialSpec;
 
-           template<typename ... Types, // expected-note{{non-deducible template parameter 'Types'}}
+  template<typename ... Types, // expected-note{{non-deducible template parameter 'Types'}}
            typename Tail> // expected-note{{non-deducible template parameter 'Tail'}}
   struct UselessPartialSpec<Types..., Tail>; // expected-warning{{class template partial specialization contains template parameters that can not be deduced; this partial specialization will never be used}}
 }
+
+namespace DeduceNonTypeTemplateArgsInArray {
+  template<typename ...ArrayTypes>
+  struct split_arrays;
+
+  template<typename ...ElementTypes, unsigned ...Bounds>
+  struct split_arrays<ElementTypes[Bounds]...> {
+    typedef tuple<ElementTypes...> element_types;
+
+    // FIXME: Would like to have unsigned_tuple<Bounds...> here.
+    typedef tuple<unsigned_c<Bounds>...> bounds_types;
+  };
+
+  int check1[is_same<split_arrays<int[1], float[2], double[3]>::element_types,
+                     tuple<int, float, double>>::value? 1 : -1];
+  int check2[is_same<split_arrays<int[1], float[2], double[3]>::bounds_types,
+                     tuple<unsigned_c<1>, unsigned_c<2>, unsigned_c<3>>
+                     >::value? 1 : -1];
+}