<div dir="ltr">Thanks!</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Apr 3, 2014 at 9:32 AM, Faisal Vali <span dir="ltr"><<a href="mailto:faisalv@yahoo.com" target="_blank">faisalv@yahoo.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: faisalv<br>
Date: Thu Apr  3 11:32:21 2014<br>
New Revision: 205543<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=205543&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=205543&view=rev</a><br>
Log:<br>
Teach getTemplateInstantiationPattern to deal with generic lambdas.<br>
<br>
No functionality change.<br>
<br>
When determining the pattern for instantiating a generic lambda call operator specialization - we must not go drilling down for the 'prototype' (i.e. as written) pattern - rather we must use our partially transformed  pattern (whose DeclRefExprs are wired correctly to any enclosing lambda's decls that should be mapped correctly in a local instantiation scope) that is the templated pattern of the specialization's primary template (even though the primary template might be instantiated from a 'prototype' member-template).  Previously, the drilling down was haltted by marking the instantiated-from primary template as a member-specialization (incorrectly).<br>

<br>
This prompted Richard to remark (<a href="http://llvm-reviews.chandlerc.com/D1784?id=4687#inline-10272" target="_blank">http://llvm-reviews.chandlerc.com/D1784?id=4687#inline-10272</a>)<br>
"It's a bit nasty to (essentially) set this bit incorrectly. Can you put the check into getTemplateInstantiationPattern instead?"<br>
<br>
In my reckless youth, I chose to ignore that comment.  With the passage of time, I have come to learn the value of bowing to the will of the angry Gods ;)<br>
<br>
<br>
<br>
Modified:<br>
    cfe/trunk/include/clang/AST/ASTLambda.h<br>
    cfe/trunk/lib/AST/Decl.cpp<br>
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp<br>
<br>
Modified: cfe/trunk/include/clang/AST/ASTLambda.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTLambda.h?rev=205543&r1=205542&r2=205543&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTLambda.h?rev=205543&r1=205542&r2=205543&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/AST/ASTLambda.h (original)<br>
+++ cfe/trunk/include/clang/AST/ASTLambda.h Thu Apr  3 11:32:21 2014<br>
@@ -36,9 +36,9 @@ inline bool isLambdaCallOperator(const D<br>
   return isLambdaCallOperator(cast<CXXMethodDecl>(DC));<br>
 }<br>
<br>
-inline bool isGenericLambdaCallOperatorSpecialization(CXXMethodDecl *MD) {<br>
+inline bool isGenericLambdaCallOperatorSpecialization(const CXXMethodDecl *MD) {<br>
   if (!MD) return false;<br>
-  CXXRecordDecl *LambdaClass = MD->getParent();<br>
+  const CXXRecordDecl *LambdaClass = MD->getParent();<br>
   if (LambdaClass && LambdaClass->isGenericLambda())<br>
     return isLambdaCallOperator(MD) &&<br>
                     MD->isFunctionTemplateSpecialization();<br>
<br>
Modified: cfe/trunk/lib/AST/Decl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=205543&r1=205542&r2=205543&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=205543&r1=205542&r2=205543&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/AST/Decl.cpp (original)<br>
+++ cfe/trunk/lib/AST/Decl.cpp Thu Apr  3 11:32:21 2014<br>
@@ -13,6 +13,7 @@<br>
<br>
 #include "clang/AST/Decl.h"<br>
 #include "clang/AST/ASTContext.h"<br>
+#include "clang/AST/ASTLambda.h"<br>
 #include "clang/AST/ASTMutationListener.h"<br>
 #include "clang/AST/Attr.h"<br>
 #include "clang/AST/DeclCXX.h"<br>
@@ -2830,14 +2831,34 @@ FunctionDecl *FunctionDecl::getTemplateI<br>
   // Handle class scope explicit specialization special case.<br>
   if (getTemplateSpecializationKind() == TSK_ExplicitSpecialization)<br>
     return getClassScopeSpecializationPattern();<br>
-<br>
+<br>
+  // If this is a generic lambda call operator specialization, its<br>
+  // instantiation pattern is always its primary template's pattern<br>
+  // even if its primary template was instantiated from another<br>
+  // member template (which happens with nested generic lambdas).<br>
+  // Since a lambda's call operator's body is transformed eagerly,<br>
+  // we don't have to go hunting for a prototype definition template<br>
+  // (i.e. instantiated-from-member-template) to use as an instantiation<br>
+  // pattern.<br>
+<br>
+  if (isGenericLambdaCallOperatorSpecialization(<br>
+          dyn_cast<CXXMethodDecl>(this))) {<br>
+    assert(getPrimaryTemplate() && "A generic lambda specialization must be "<br>
+                                   "generated from a primary call operator "<br>
+                                   "template");<br>
+    assert(getPrimaryTemplate()->getTemplatedDecl()->getBody() &&<br>
+           "A generic lambda call operator template must always have a body - "<br>
+           "even if instantiated from a prototype (i.e. as written) member "<br>
+           "template");<br>
+    return getPrimaryTemplate()->getTemplatedDecl();<br>
+  }<br>
+<br>
   if (FunctionTemplateDecl *Primary = getPrimaryTemplate()) {<br>
     while (Primary->getInstantiatedFromMemberTemplate()) {<br>
       // If we have hit a point where the user provided a specialization of<br>
       // this template, we're done looking.<br>
       if (Primary->isMemberSpecialization())<br>
         break;<br>
-<br>
       Primary = Primary->getInstantiatedFromMemberTemplate();<br>
     }<br>
<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=205543&r1=205542&r2=205543&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=205543&r1=205542&r2=205543&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Thu Apr  3 11:32:21 2014<br>
@@ -837,8 +837,6 @@ namespace {<br>
                               OldCallOperator->getDescribedFunctionTemplate();<br>
         NewCallOperatorTemplate->setInstantiatedFromMemberTemplate(<br>
                                                      OldCallOperatorTemplate);<br>
-        // Mark the NewCallOperatorTemplate a specialization.<br>
-        NewCallOperatorTemplate->setMemberSpecialization();<br>
       } else<br>
         // For a non-generic lambda we set the NewCallOperator to<br>
         // be an instantiation of the OldCallOperator.<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>