r210355 - Retain an expression pack expansion when the parameter pack expansion code asks

Richard Smith richard-llvm at metafoo.co.uk
Fri Jun 6 10:33:36 PDT 2014


Author: rsmith
Date: Fri Jun  6 12:33:35 2014
New Revision: 210355

URL: http://llvm.org/viewvc/llvm-project?rev=210355&view=rev
Log:
Retain an expression pack expansion when the parameter pack expansion code asks
us to.

Modified:
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/test/SemaTemplate/pack-deduction.cpp

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=210355&r1=210354&r2=210355&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Fri Jun  6 12:33:35 2014
@@ -2912,9 +2912,11 @@ bool TreeTransform<Derived>::TransformEx
         if (Out.isInvalid())
           return true;
 
+        // FIXME: Can this happen? We should not try to expand the pack
+        // in this case.
         if (Out.get()->containsUnexpandedParameterPack()) {
-          Out = RebuildPackExpansion(Out.get(), Expansion->getEllipsisLoc(),
-                                     OrigNumExpansions);
+          Out = getDerived().RebuildPackExpansion(
+              Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
           if (Out.isInvalid())
             return true;
         }
@@ -2922,6 +2924,23 @@ bool TreeTransform<Derived>::TransformEx
         Outputs.push_back(Out.get());
       }
 
+      // If we're supposed to retain a pack expansion, do so by temporarily
+      // forgetting the partially-substituted parameter pack.
+      if (RetainExpansion) {
+        ForgetPartiallySubstitutedPackRAII Forget(getDerived());
+
+        ExprResult Out = getDerived().TransformExpr(Pattern);
+        if (Out.isInvalid())
+          return true;
+
+        Out = getDerived().RebuildPackExpansion(
+            Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
+        if (Out.isInvalid())
+          return true;
+
+        Outputs.push_back(Out.get());
+      }
+
       continue;
     }
 
@@ -8618,6 +8637,9 @@ TreeTransform<Derived>::TransformLambdaS
           // Capture the transformed variable.
           getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
         }
+
+        // FIXME: Retain a pack expansion if RetainExpansion is true.
+
         continue;
       }
 
@@ -9122,6 +9144,7 @@ TreeTransform<Derived>::TransformObjCDic
 
         // If any unexpanded parameter packs remain, we still have a
         // pack expansion.
+        // FIXME: Can this really happen?
         if (Key.get()->containsUnexpandedParameterPack() ||
             Value.get()->containsUnexpandedParameterPack())
           Element.EllipsisLoc = OrigElement.EllipsisLoc;
@@ -9129,6 +9152,8 @@ TreeTransform<Derived>::TransformObjCDic
         Elements.push_back(Element);
       }
 
+      // FIXME: Retain a pack expansion if RetainExpansion is true.
+
       // We've finished with this pack expansion.
       continue;
     }

Modified: cfe/trunk/test/SemaTemplate/pack-deduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/pack-deduction.cpp?rev=210355&r1=210354&r2=210355&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/pack-deduction.cpp (original)
+++ cfe/trunk/test/SemaTemplate/pack-deduction.cpp Fri Jun  6 12:33:35 2014
@@ -30,3 +30,10 @@ namespace PR14841 {
     f<char, short, int>(a); // expected-error {{no matching function}}
   }
 }
+
+namespace RetainExprPacks {
+  int f(int a, int b, int c);
+  template<typename ...Ts> struct X {};
+  template<typename ...Ts> int g(X<Ts...>, decltype(f(Ts()...)));
+  int n = g<int, int>(X<int, int, int>(), 0);
+}





More information about the cfe-commits mailing list