Author: rsmith
Date: Wed Apr 19 20:15:31 2017
New Revision: 300805

URL: http://llvm.org/viewvc/llvm-project?rev=300805&view=rev
Log:
PR32673: Don't wrap parameter packs in SubstTemplateTypeParmPackType nodes when 
forming implicit deduction guides.

Doing so thwarts template type deduction. Instead, substitute the pack directly
by picking "slice 0" of the resulting expansion.

Modified:
    cfe/trunk/include/clang/AST/TypeLoc.h
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp

Modified: cfe/trunk/include/clang/AST/TypeLoc.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLoc.h?rev=300805&r1=300804&r2=300805&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/TypeLoc.h (original)
+++ cfe/trunk/include/clang/AST/TypeLoc.h Wed Apr 19 20:15:31 2017
@@ -1544,7 +1544,11 @@ class DependentSizedArrayTypeLoc :
     public InheritingConcreteTypeLoc<ArrayTypeLoc,
                                      DependentSizedArrayTypeLoc,
                                      DependentSizedArrayType> {
-
+public:
+  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
+    ArrayTypeLoc::initializeLocal(Context, Loc);
+    setSizeExpr(getTypePtr()->getSizeExpr());
+  }
 };
 
 class VariableArrayTypeLoc :

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=300805&r1=300804&r2=300805&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Apr 19 20:15:31 2017
@@ -1636,11 +1636,22 @@ private:
   transformFunctionTypeParam(ParmVarDecl *OldParam,
                              MultiLevelTemplateArgumentList &Args) {
     TypeSourceInfo *OldDI = OldParam->getTypeSourceInfo();
-    TypeSourceInfo *NewDI =
-        Args.getNumLevels()
-            ? SemaRef.SubstType(OldDI, Args, OldParam->getLocation(),
-                                OldParam->getDeclName())
-            : OldDI;
+    TypeSourceInfo *NewDI;
+    if (!Args.getNumLevels())
+      NewDI = OldDI;
+    else if (auto PackTL = OldDI->getTypeLoc().getAs<PackExpansionTypeLoc>()) {
+      // Expand out the one and only element in each inner pack.
+      Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, 0);
+      NewDI =
+          SemaRef.SubstType(PackTL.getPatternLoc(), Args,
+                            OldParam->getLocation(), OldParam->getDeclName());
+      if (!NewDI) return nullptr;
+      NewDI =
+          SemaRef.CheckPackExpansion(NewDI, PackTL.getEllipsisLoc(),
+                                     PackTL.getTypePtr()->getNumExpansions());
+    } else
+      NewDI = SemaRef.SubstType(OldDI, Args, OldParam->getLocation(),
+                                OldParam->getDeclName());
     if (!NewDI)
       return nullptr;
 

Modified: cfe/trunk/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp?rev=300805&r1=300804&r2=300805&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp 
(original)
+++ cfe/trunk/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp Wed Apr 
19 20:15:31 2017
@@ -213,3 +213,38 @@ namespace transform_params {
   };
   D d(Y<0, 1, 2>{});
 }
+
+namespace variadic {
+  int arr3[3], arr4[4];
+
+  // PR32673
+  template<typename T> struct A {
+    template<typename ...U> A(T, U...);
+  };
+  A a(1, 2, 3);
+
+  template<typename T> struct B {
+    template<int ...N> B(T, int (&...r)[N]);
+  };
+  B b(1, arr3, arr4);
+
+  template<typename T> struct C {
+    template<template<typename> typename ...U> C(T, U<int>...);
+  };
+  C c(1, a, b);
+
+  template<typename ...U> struct X {
+    template<typename T> X(T, U...);
+  };
+  X x(1, 2, 3);
+
+  template<int ...N> struct Y {
+    template<typename T> Y(T, int (&...r)[N]);
+  };
+  Y y(1, arr3, arr4);
+
+  template<template<typename> typename ...U> struct Z {
+    template<typename T> Z(T, U<int>...);
+  };
+  Z z(1, a, b);
+}


_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to