r205543 - Teach getTemplateInstantiationPattern to deal with generic lambdas.
Richard Smith
richard at metafoo.co.uk
Thu Apr 3 11:05:08 PDT 2014
Thanks!
On Thu, Apr 3, 2014 at 9:32 AM, Faisal Vali <faisalv at yahoo.com> wrote:
> Author: faisalv
> Date: Thu Apr 3 11:32:21 2014
> New Revision: 205543
>
> URL: http://llvm.org/viewvc/llvm-project?rev=205543&view=rev
> Log:
> Teach getTemplateInstantiationPattern to deal with generic lambdas.
>
> No functionality change.
>
> 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).
>
> This prompted Richard to remark (
> http://llvm-reviews.chandlerc.com/D1784?id=4687#inline-10272)
> "It's a bit nasty to (essentially) set this bit incorrectly. Can you put
> the check into getTemplateInstantiationPattern instead?"
>
> 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 ;)
>
>
>
> Modified:
> cfe/trunk/include/clang/AST/ASTLambda.h
> cfe/trunk/lib/AST/Decl.cpp
> cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
>
> Modified: cfe/trunk/include/clang/AST/ASTLambda.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTLambda.h?rev=205543&r1=205542&r2=205543&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/AST/ASTLambda.h (original)
> +++ cfe/trunk/include/clang/AST/ASTLambda.h Thu Apr 3 11:32:21 2014
> @@ -36,9 +36,9 @@ inline bool isLambdaCallOperator(const D
> return isLambdaCallOperator(cast<CXXMethodDecl>(DC));
> }
>
> -inline bool isGenericLambdaCallOperatorSpecialization(CXXMethodDecl *MD) {
> +inline bool isGenericLambdaCallOperatorSpecialization(const CXXMethodDecl
> *MD) {
> if (!MD) return false;
> - CXXRecordDecl *LambdaClass = MD->getParent();
> + const CXXRecordDecl *LambdaClass = MD->getParent();
> if (LambdaClass && LambdaClass->isGenericLambda())
> return isLambdaCallOperator(MD) &&
> MD->isFunctionTemplateSpecialization();
>
> Modified: cfe/trunk/lib/AST/Decl.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=205543&r1=205542&r2=205543&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/Decl.cpp (original)
> +++ cfe/trunk/lib/AST/Decl.cpp Thu Apr 3 11:32:21 2014
> @@ -13,6 +13,7 @@
>
> #include "clang/AST/Decl.h"
> #include "clang/AST/ASTContext.h"
> +#include "clang/AST/ASTLambda.h"
> #include "clang/AST/ASTMutationListener.h"
> #include "clang/AST/Attr.h"
> #include "clang/AST/DeclCXX.h"
> @@ -2830,14 +2831,34 @@ FunctionDecl *FunctionDecl::getTemplateI
> // Handle class scope explicit specialization special case.
> if (getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
> return getClassScopeSpecializationPattern();
> -
> +
> + // If this is a generic lambda call operator specialization, its
> + // instantiation pattern is always its primary template's pattern
> + // even if its primary template was instantiated from another
> + // member template (which happens with nested generic lambdas).
> + // Since a lambda's call operator's body is transformed eagerly,
> + // we don't have to go hunting for a prototype definition template
> + // (i.e. instantiated-from-member-template) to use as an instantiation
> + // pattern.
> +
> + if (isGenericLambdaCallOperatorSpecialization(
> + dyn_cast<CXXMethodDecl>(this))) {
> + assert(getPrimaryTemplate() && "A generic lambda specialization must
> be "
> + "generated from a primary call
> operator "
> + "template");
> + assert(getPrimaryTemplate()->getTemplatedDecl()->getBody() &&
> + "A generic lambda call operator template must always have a
> body - "
> + "even if instantiated from a prototype (i.e. as written)
> member "
> + "template");
> + return getPrimaryTemplate()->getTemplatedDecl();
> + }
> +
> if (FunctionTemplateDecl *Primary = getPrimaryTemplate()) {
> while (Primary->getInstantiatedFromMemberTemplate()) {
> // If we have hit a point where the user provided a specialization
> of
> // this template, we're done looking.
> if (Primary->isMemberSpecialization())
> break;
> -
> Primary = Primary->getInstantiatedFromMemberTemplate();
> }
>
>
> Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=205543&r1=205542&r2=205543&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Thu Apr 3 11:32:21 2014
> @@ -837,8 +837,6 @@ namespace {
>
> OldCallOperator->getDescribedFunctionTemplate();
> NewCallOperatorTemplate->setInstantiatedFromMemberTemplate(
>
> OldCallOperatorTemplate);
> - // Mark the NewCallOperatorTemplate a specialization.
> - NewCallOperatorTemplate->setMemberSpecialization();
> } else
> // For a non-generic lambda we set the NewCallOperator to
> // be an instantiation of the OldCallOperator.
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140403/a953cdba/attachment.html>
More information about the cfe-commits
mailing list